package com.thinkingcoder.tcregistry;

import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.thinkingcoder.tcregistry.cluster.Cluster;
import com.thinkingcoder.tcregistry.cluster.Server;
import com.thinkingcoder.tcregistry.cluster.Snapshot;
import com.thinkingcoder.tcregistry.model.meta.InstanceMeta;
import com.thinkingcoder.tcregistry.service.RegistryService;
import com.thinkingcoder.tcregistry.service.TcRegistryService;

import lombok.extern.slf4j.Slf4j;

@RestController
@Slf4j
public class TcRegistryController {

    @Autowired
    RegistryService registryService;

    @Autowired
    Cluster cluster;

    /**
     * 用于服务注册
     * 
     * @param serviceName 服务名称
     * @param instance 服务
     * @return
     */
    @RequestMapping("/reg")
    public InstanceMeta register(@RequestParam("serviceName") String serviceName, @RequestBody InstanceMeta instance) {
        log.info(" ===> register {} @ {}", serviceName, instance);
        checkLeader();
        return registryService.register(serviceName, instance);
    }

    private void checkLeader() {
        if (!cluster.self().isLeader()) {
            throw new RuntimeException("current server is not a leader, the leader is " + cluster.leader().getUrl());
        }
    }

    @RequestMapping("/unReg")
    public InstanceMeta unRegistry(@RequestParam("serviceName") String serviceName,
        @RequestBody InstanceMeta instance) {
        log.info(" ===> unregister {} @ {}", serviceName, instance);
        checkLeader();
        return registryService.unregister(serviceName, instance);
    }

    @RequestMapping("/findAll")
    public List<InstanceMeta> findAll(@RequestParam("serviceName") String serviceName) {
        log.info(" ===> findAllInstances {}", serviceName);
        return registryService.getAllInstances(serviceName);
    }

    @RequestMapping("/renew")
    public Long renew(@RequestParam("serviceName") String serviceName, @RequestBody InstanceMeta instance) {
        log.info(" ===> renew {} @ {}", serviceName, instance);
        checkLeader();
        return registryService.renew(instance, serviceName);
    }

    @RequestMapping("/renews")
    public Long renews(@RequestParam("serviceNames") String serviceNames, @RequestBody InstanceMeta instance) {
        log.info(" ===> renews {} @ {}", serviceNames, instance);
        checkLeader();
        return registryService.renew(instance, serviceNames.split(","));
    }

    @RequestMapping("/version")
    public Long version(@RequestParam("serviceName") String serviceName) {
        log.info(" ===> version {}", serviceName);
        return registryService.version(serviceName);
    }

    @RequestMapping("/versions")
    public Map<String, Long> versions(@RequestParam("serviceNames") String serviceNames) {
        log.info(" ===> versions {}", serviceNames);
        return registryService.versions(serviceNames.split(","));
    }

    @RequestMapping("/info")
    public Server info() {
        Server self = cluster.self();
        log.info(" ===> info: {}", self);
        return self;
    }

    @RequestMapping("/cluster")
    public List<Server> cluster() {
        List<Server> servers = cluster.getServers();
        log.info(" ===> cluster: {}", servers);
        return servers;
    }

    @RequestMapping("/leader")
    public Server leader() {
        Server leader = cluster.leader();
        log.info(" ===> leader: {}", leader);
        return leader;
    }

    @RequestMapping("/sl")
    public Server sl() {
        Server self = cluster.self();
        self.setLeader(true);
        log.info(" ===> leader: {}", self);
        return self;
    }

    @RequestMapping("/snapshot")
    public Snapshot snapshot() {
        return TcRegistryService.snapshot();
    }
}
